package utils;

import beans.HttpConfig;
import beans.SocketLogRecordInfo;
import engine.BIEngine0_1.AlgorithmThread;
import engine.BIEngine0_1.TaskThread;
import org.apache.tools.zip.ZipFile;
import org.apache.commons.io.FileUtils;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class StaticUtil {
	private static SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");

	public static String getJhJobCommand(String taskId,String algorithmId,String fileName){
		return "/"+taskId+"/"+algorithmId+"/"+fileName;
	}

	public static String zipFile(String filePath) throws Exception {
		String postfix = filePath.substring(filePath.lastIndexOf("."),filePath.length());
		String zipFileName = filePath.replaceAll(postfix,".zip");
		ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
		BufferedOutputStream bo = new BufferedOutputStream(out);
		File inputFile = new File(filePath);
		zip(out, inputFile, inputFile.getName(), bo);
		bo.close();
		out.close(); // 输出流关闭
		return zipFileName;
//        Log4jInit.logger.info("压缩完成");
	}

	private static void zip(ZipOutputStream out, File f, String base,
							BufferedOutputStream bo) throws Exception { // 方法重载
		if (f.isDirectory()) {
			File[] fl = f.listFiles();
			if (fl.length == 0) {
				out.putNextEntry(new ZipEntry(base + "/")); // 创建zip压缩进入点base
			}
			for (int i = 0; i < fl.length; i++) {
				zip(out, fl[i], base + "/" + fl[i].getName(), bo); // 递归遍历子文件夹
			}
		} else {
			out.putNextEntry(new ZipEntry(base)); // 创建zip压缩进入点base
			FileInputStream in = new FileInputStream(f);
			BufferedInputStream bi = new BufferedInputStream(in);
			int b;
			while ((b = bi.read()) != -1) {
				bo.write(b); // 将字节流写入当前zip目录
			}
			bi.close();
			in.close(); // 输入流关闭
		}
	}

	/**
	 * 获取文件夹下所有文件
	 * @param path
	 */
	public static List<String> getAllFiles(String path, String foldName, String executeAlgorithmFileName){
		File root = new File(path);

		if(root.isDirectory()){
			File[] files = root.listFiles();
			List<String>  rtFile = new ArrayList<String>();;
			if(files != null){
				for(int i=0;i<files.length;i++){
					if(files[i].isFile()){
						//zip文件添加一层目录，且不上传同名xml文件——2018-4-27
						if(!files[i].getAbsolutePath().contains(foldName+".xml")){
							rtFile.add(files[i].getAbsolutePath().replaceAll("\\\\","/"));
						}
						//这段是为中文算法zip包里面涉及到的中文名称改变为uuid
//						if(files[i].getAbsolutePath().contains(foldName+".exe")){
//							String filePath = files[i].getAbsolutePath();
//							filePath = filePath.replaceAll("\\\\","/");
//							String targetPath = filePath.substring(0, filePath.lastIndexOf("/")+1)+executeAlgorithmFileName+".exe";
//							try {
//								FileUtils.copyFile(new File(filePath), new File(targetPath));
//								rtFile.add(targetPath.replaceAll("\\\\","/"));
//							} catch (IOException e) {
//								return null;
//							}
//						}
					}else{
						List<String> rtFile2=getAllFiles(files[i].getAbsolutePath(),foldName,executeAlgorithmFileName);
						rtFile.addAll(rtFile2);
					}
				}
			}
//			for(String one:rtFile){
//				Log4jInit.logger.info("zipped file:"+one);
//			}
			return rtFile;
		}else{
			Log4jInit.logger.info("Empty root!");
			return null;
		}
	}

	/**
	 * 解压zip包到同名文件夹
	 * @param path
	 */
	public static void unzip(String path){
		int count = -1;
		String savepath = "";
		int buffer = 204800;
		File file = null;
		InputStream is = null;
		FileOutputStream fos = null;
		BufferedOutputStream bos = null;

		savepath = path.substring(0, path.lastIndexOf(".")) + File.separator; //保存解压文件目录
		new File(savepath).mkdir(); //创建保存目录
		ZipFile zipFile = null;
		try
		{
			zipFile = new ZipFile(path,"gbk"); //解决中文乱码问题
			Enumeration<?> entries = zipFile.getEntries();

			while(entries.hasMoreElements())
			{
				byte buf[] = new byte[buffer];

				org.apache.tools.zip.ZipEntry entry = (org.apache.tools.zip.ZipEntry)entries.nextElement();

				String filename = entry.getName();
				boolean ismkdir = false;
				if(filename.lastIndexOf("/") != -1){ //检查此文件是否带有文件夹
					ismkdir = true;
				}
				filename = savepath + filename;

				if(entry.isDirectory()){ //如果是文件夹先创建
					file = new File(filename);
					file.mkdirs();
					continue;
				}
				file = new File(filename);
				if(!file.exists()){ //如果是目录先创建
					if(ismkdir){
						new File(filename.substring(0, filename.lastIndexOf("/"))).mkdirs(); //目录先创建
					}
				}
				file.createNewFile(); //创建文件

				is = zipFile.getInputStream(entry);
				fos = new FileOutputStream(file);
				bos = new BufferedOutputStream(fos, buffer);

				while((count = is.read(buf)) > -1)
				{
					bos.write(buf, 0, count);
				}
				bos.flush();
				bos.close();
				fos.close();

				is.close();
			}

			zipFile.close();

		}catch(IOException ioe){
			ioe.printStackTrace();
		}finally{
			try{
				if(bos != null){
					bos.close();
				}
				if(fos != null) {
					fos.close();
				}
				if(is != null){
					is.close();
				}
				if(zipFile != null){
					zipFile.close();
				}
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void cpFile(String filePath, String targetPath) throws IOException {
		if(HttpConfig.serverPlatform.equals("linux")) {
			File targetFold = new File(targetPath);
			if(!targetFold.exists()){
				targetFold.mkdir();
			}
			BufferedReader br = new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec("cp " + filePath + " " + targetPath).getInputStream()));
			String line = null;
			StringBuffer stringBuffer = new StringBuffer();
			while((line=br.readLine())!=null){
				stringBuffer.append(line+"\n");

			}
			Log4jInit.logger.info("cp file print:"+stringBuffer.toString());
		}else{
			String fileName = filePath.substring(filePath.lastIndexOf("/")+1,filePath.length());
			String targetFilePath = targetPath+fileName;
			FileUtils.copyFile(new File(filePath), new File(targetFilePath));
		}
	}

	public static boolean deleteFile(String filePath){
		File file = new File(filePath);
		// 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
		if (file.exists()) {
			if (file.delete()) {
//                Log4jInit.logger.info("删除单个文件" + filePath + "成功！");
                return true;
			} else {
//				Log4jInit.logger.info("删除单个文件" + filePath + "失败！");
				return false;
			}
		} else {
//			Log4jInit.logger.info("删除单个文件失败：" + filePath + "不存在！");
			return false;
		}
	}

	public static String getUriDelimiter(){
		if(HttpConfig.serverPlatform.equals("linux")){
			return "/";
		}else{
			return "\\";
		}
	}

	/**
	 * 保留原始ini文件中的SERVERIP和PORT值
	 * PSN值替换为批量任务名称+时间,  update:subtaskhash
	 * ID值替换为算法名称
	 * LEVEL值替换为static.properties中的socketLogLevel值
	 * 最后新创建一个ini文件在targetFileUri目录下
	 * @param algorithmThread
	 * @param algorithmName
	 * @param iniFileUri
	 * @param targetFileUri
	 * @return
	 */
	public static String createIniFile(AlgorithmThread algorithmThread, String algorithmHash, String algorithmName, String iniFileUri, String targetFileUri,String psn){
		try {
			String logLevel = HttpConfig.socketLogLevel;
			BufferedReader iniFileReader = new BufferedReader(new FileReader(new File(iniFileUri)));
			StringBuffer iniFileString = new StringBuffer();
			String temp = "";
//			String psn = algorithmThread.fatherTask.runningTaskBean.getTaskName() + "--" + sf.format(new Date());
			String id = algorithmName;
			while((temp = iniFileReader.readLine())!=null){
				if(temp.contains("ID=")){
					temp = temp.substring(0,temp.indexOf("=")+1) + id;
				}
				if(temp.contains("PSN=")){
					temp = temp.substring(0,temp.indexOf("=")+1) + psn;
					Log4jInit.logger.info("******PSN:"+psn);
				}
				if(temp.contains("LEVEL=")){
					temp = temp.substring(0,temp.indexOf("=")+1) + logLevel;
				}
				iniFileString.append(temp+"\r\n");
			}
			targetFileUri = targetFileUri+psn+"/";
			new File(targetFileUri).mkdir();
			String result = iniFileString.toString().substring(0,iniFileString.toString().lastIndexOf("\r\n"));
			String fileName = targetFileUri+iniFileUri.substring(iniFileUri.lastIndexOf("/")+1, iniFileUri.length());
			File targetFile = new File(fileName);
			BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(targetFile));
			bufferedWriter.write(result);
			bufferedWriter.close();
			SocketLogRecordInfo socketLogRecordInfo = new SocketLogRecordInfo();
			socketLogRecordInfo.setId(id);
			socketLogRecordInfo.setPsn(psn);
			//2018-7-14 这里需要将创建ini文件时产生的psn值和id值存到TaskThread对象的runningtaskBean的socketlogRecordInfo里面去，便于job启动之后将相关的日志信息记录到数据库中
			if(null!=algorithmThread){
				Map<String,SocketLogRecordInfo> map = new HashMap<>();
				String key = algorithmThread.fatherTask.runningTaskBean.getTaskHash()+algorithmHash;
				map.put(key,socketLogRecordInfo);
	         algorithmThread.setSocketLogRecordInfos(map);
			}
			return fileName;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static void main(String[] args) throws IOException {
//		unzip("D:/121/地形_测绘_DEM生成.zip");
//		unzip("D:/地形_测绘_DEM生成.zip");
		Log4jInit.logger.info(sf.format(new Date()));
//		unzip("D:/121.zip");
//		unzip("D:/cpuRc12.zip");
//		String algorithmName = "test algorithm name";
//		String taskName = "test task name";
//		String iniFileUri = Thread.currentThread().getContextClassLoader().getResource("config.ini").getPath();
//		String a = "E:/config.ini";
//		File file = new File(a);
//		String b = "E:/cconfig.ini";
//		File bFile = new File(b);
//		file.renameTo(bFile);
//		Log4jInit.logger.info(iniFileUri);
//		String aa = "D:\\Documents\\JCPT\\code\\406\\cpuRc12\\cpuRc12\\cpuRc12\\cpuRc12.exe";
//		Log4jInit.logger.info(aa.lastIndexOf("\\"));
//		deleteFile("D:/Documents/JCPT/code/406/cpuRc12/cpuRc12/cpuRc12/1c9-496e-b845-655bcd1348b4.exe");
	}

	/**
	 * 解压zip包不带文件夹
	 * @param path
	 */
	@SuppressWarnings("Duplicates")
	public static List<String> unzipWithoutOuterFolder(String path, String savePath){
		int count = -1;
		int buffer = 204800;
		File file = null;
		InputStream is = null;
		FileOutputStream fos = null;
		BufferedOutputStream bos = null;
		List<String> modelXmlDirList = new ArrayList<>();
		
		

		ZipFile zipFile = null;
		try
		{
			zipFile = new ZipFile(path,"gbk"); //解决中文乱码问题
			
			Enumeration<?> entries = zipFile.getEntries();

			while(entries.hasMoreElements())
			{
				byte buf[] = new byte[buffer];

				org.apache.tools.zip.ZipEntry entry = (org.apache.tools.zip.ZipEntry)entries.nextElement();

				Log4jInit.logger.info(entry.getName());
				String filename = entry.getName();
				if(filename.endsWith("/"))
					continue;
				//Log4jInit.logger.info("=========="+filename);
				filename = savePath + "/" + filename;
				modelXmlDirList.add(filename);
				///Log4jInit.logger.info(filename);
				file = new File(filename);
				file.createNewFile(); //创建文件

				is = zipFile.getInputStream(entry);
				fos = new FileOutputStream(file);
				bos = new BufferedOutputStream(fos, buffer);

				while((count = is.read(buf)) > -1)
				{
					bos.write(buf, 0, count);
				}
				bos.flush();
				bos.close();
				fos.close();

				is.close();
			}

			zipFile.close();

		}catch(IOException ioe){
			ioe.printStackTrace();
		}finally{
			try{
				if(bos != null){
					bos.close();
				}
				if(fos != null) {
					fos.close();
				}
				if(is != null){
					is.close();
				}
				if(zipFile != null){
					zipFile.close();
				}
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		return modelXmlDirList;
	}
}
